home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / IMGPROC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.8 KB  |  289 lines

  1.  
  2. /* imgproc.c - by David Blythe, SGI */
  3.  
  4. /* Examples of various image processing operations coded as OpenGL
  5.    accumulation buffer operations.  This allows extremely fast   
  6.    image processing on machines with hardware accumulation buffers
  7.    (RealityEngine, InfiniteReality, VGX). */
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <GL/glut.h>
  13. #include "texture.h"
  14.  
  15. static unsigned *image, *null;
  16. static int width, height, components;
  17. static void (*func) (void);
  18. static float alpha = 1.;
  19. static float luma = .5;
  20. static int reset = 1;
  21. static int format = GL_RGBA;
  22.  
  23. void
  24. brighten(void)
  25. {
  26.   if (reset) {
  27.     memset(null, 0, width * height * sizeof *null);
  28.     reset = 0;
  29.   }
  30.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image);
  31.   glAccum(GL_LOAD, alpha / 2.);
  32.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null);
  33.   glAccum(GL_ACCUM, (1 - alpha) / 2.);
  34.   glAccum(GL_RETURN, 2.0);
  35. }
  36.  
  37. void
  38. saturate(void)
  39. {
  40.   if (reset) {
  41.     memset(null, 0xff, width * height * sizeof *null);
  42.     reset = 0;
  43.   }
  44.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image);
  45.   glAccum(GL_LOAD, alpha / 2.);
  46.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null);
  47.   glAccum(GL_ACCUM, (1 - alpha) / 2.);
  48.   glAccum(GL_RETURN, 2.0);
  49. }
  50.  
  51. void
  52. contrast(void)
  53. {
  54.   if (reset) {
  55.     memset(null, luma, width * height * sizeof *null);
  56.     reset = 0;
  57.   }
  58.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image);
  59.   glAccum(GL_LOAD, alpha / 2.);
  60.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null);
  61.   glAccum(GL_ACCUM, (1 - alpha) / 2.);
  62.   glAccum(GL_RETURN, 2.0);
  63. }
  64.  
  65. void
  66. balance(void)
  67. {
  68.   if (reset) {
  69.     memset(null, luma, width * height * sizeof *null);
  70.     reset = 0;
  71.   }
  72.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image);
  73.   glAccum(GL_LOAD, alpha / 2.);
  74.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null);
  75.   glAccum(GL_ACCUM, (1 - alpha) / 2.);
  76.   glAccum(GL_RETURN, 2.0);
  77. }
  78.  
  79. void
  80. sharpen(void)
  81. {
  82.   if (reset) {
  83.     gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
  84.       width / 4, height / 4, GL_UNSIGNED_BYTE, null);
  85.     gluScaleImage(format, width / 4, height / 4, GL_UNSIGNED_BYTE, null,
  86.       width, height, GL_UNSIGNED_BYTE, null);
  87.     reset = 0;
  88.   }
  89.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image);
  90.   glAccum(GL_LOAD, alpha / 2.);
  91.   glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null);
  92.   glAccum(GL_ACCUM, (1 - alpha) / 2.);
  93.   glAccum(GL_RETURN, 2.0);
  94. }
  95.  
  96. void 
  97. set_brighten(void)
  98. {
  99.   func = brighten;
  100.   reset = 1;
  101.   printf("brighten\n");
  102. }
  103.  
  104. void 
  105. set_saturate(void)
  106. {
  107.   func = saturate;
  108.   reset = 1;
  109.   printf("saturate\n");
  110. }
  111.  
  112. void 
  113. set_contrast(void)
  114. {
  115.   func = contrast;
  116.   reset = 1;
  117.   printf("contrast\n");
  118. }
  119.  
  120. void 
  121. set_balance(void)
  122. {
  123.   func = balance;
  124.   reset = 1;
  125.   printf("balance\n");
  126. }
  127.  
  128. void 
  129. set_sharpen(void)
  130. {
  131.   func = sharpen;
  132.   reset = 1;
  133.   printf("sharpen\n");
  134. }
  135.  
  136. void
  137. help(void)
  138. {
  139.   printf("'h'   - help\n");
  140.   printf("'b'   - brighten\n");
  141.   printf("'s'   - saturate\n");
  142.   printf("'c'   - contrast\n");
  143.   printf("'z'   - sharpen\n");
  144.   printf("'a'   - color balance\n");
  145.   printf("left mouse     - increase alpha\n");
  146.   printf("middle mouse   - decrease alpha\n");
  147. }
  148.  
  149. void
  150. init(char *filename)
  151. {
  152.   double l = 0;
  153.   int i;
  154.  
  155.   func = brighten;
  156.  
  157.   if (filename) {
  158.     image = read_texture(filename, &width, &height, &components);
  159.     if (image == NULL) {
  160.       fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  161.         filename);
  162.       exit(1);
  163.     } else {
  164.       printf("%d x %d image loaded\n", width, height);
  165.     }
  166.     if (components < 3 || components > 4) {
  167.       printf("must be RGB or RGBA image\n");
  168.       exit(1);
  169.     }
  170.   } else {
  171.     int i, j;
  172.     components = 4;
  173.     width = height = 512;
  174.     image = (unsigned *) malloc(width * height * sizeof(unsigned));
  175.     for (j = 0; j < height; j++)
  176.       for (i = 0; i < width; i++) {
  177.         if (i & 1)
  178.           image[i + j * width] = 0xff;
  179.         else
  180.           image[i + j * width] = 0xff00;
  181.         if (j & 1)
  182.           image[i + j * width] |= 0xff0000;
  183.       }
  184.  
  185.   }
  186.   null = (unsigned *) malloc(width * height * sizeof *image);
  187.  
  188.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  189.   glClearColor(.25, .25, .25, .25);
  190.  
  191.   /* compute luminance */
  192.   for (i = 0; i < width * height; i++) {
  193.     GLubyte *p = (GLubyte *) (image + i);
  194.     double r = p[0] / 255.;
  195.     double g = p[1] / 255.;
  196.     double b = p[2] / 255.;
  197.     l += r * .3086 + g * .0820 + b * .114;
  198.   }
  199.   luma = l / (width * height);
  200.   printf("average luminance = %f\n", luma);
  201. }
  202.  
  203. void
  204. display(void)
  205. {
  206.   printf("alpha = %f\n", alpha);
  207.   glClear(GL_COLOR_BUFFER_BIT);
  208.   (*func) ();
  209.   glutSwapBuffers();
  210. }
  211.  
  212. void
  213. reshape(int w, int h)
  214. {
  215.   glViewport(0, 0, w, h);
  216.   glMatrixMode(GL_PROJECTION);
  217.   glLoadIdentity();
  218.   glOrtho(0., (GLdouble) width, 0., (GLdouble) height, -1., 1.);
  219.   glMatrixMode(GL_MODELVIEW);
  220.   glLoadIdentity();
  221. }
  222.  
  223. /* ARGSUSED1 */
  224. void
  225. key(unsigned char key, int x, int y)
  226. {
  227.   switch (key) {
  228.   case 'b':
  229.     set_brighten();
  230.     break;
  231.   case 's':
  232.     set_saturate();
  233.     break;
  234.   case 'c':
  235.     set_contrast();
  236.     break;
  237.   case 'z':
  238.     set_sharpen();
  239.     break;
  240.   case 'a':
  241.     set_balance();
  242.     break;
  243.   case 'h':
  244.     help();
  245.     break;
  246.   case '\033':
  247.     exit(0);
  248.     break;
  249.   default:
  250.     return;
  251.   }
  252.   glutPostRedisplay();
  253. }
  254.  
  255. /* ARGSUSED2 */
  256. void
  257. mouse(int button, int state, int x, int y)
  258. {
  259.   if (state == GLUT_DOWN) {
  260.     switch (button) {
  261.     case GLUT_LEFT_BUTTON:
  262.       alpha += .1;
  263.       break;
  264.     case GLUT_MIDDLE_BUTTON:
  265.       alpha -= .1;
  266.       break;
  267.     case GLUT_RIGHT_BUTTON:
  268.       break;
  269.     }
  270.   }
  271.   glutPostRedisplay();
  272. }
  273.  
  274. int
  275. main(int argc, char **argv)
  276. {
  277.   glutInit(&argc, argv);
  278.   glutInitWindowSize(512, 512);
  279.   glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM | GLUT_DOUBLE);
  280.   (void) glutCreateWindow("imgproc");
  281.   init(argv[1]);
  282.   glutDisplayFunc(display);
  283.   glutKeyboardFunc(key);
  284.   glutReshapeFunc(reshape);
  285.   glutMouseFunc(mouse);
  286.   glutMainLoop();
  287.   return 0;             /* ANSI C requires main to return int. */
  288. }
  289.